home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / nt / source.exe / POSIX / LS / LS.C < prev    next >
C/C++ Source or Header  |  1993-06-23  |  18KB  |  751 lines

  1. /*
  2.  * Copyright (c) 1989 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * This code is derived from software contributed to Berkeley by
  6.  * Michael Fischbein.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in the
  15.  *    documentation and/or other materials provided with the distribution.
  16.  * 3. All advertising materials mentioning features or use of this software
  17.  *    must display the following acknowledgement:
  18.  *    This product includes software developed by the University of
  19.  *    California, Berkeley and its contributors.
  20.  * 4. Neither the name of the University nor the names of its contributors
  21.  *    may be used to endorse or promote products derived from this software
  22.  *    without specific prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34.  * SUCH DAMAGE.
  35.  */
  36. #ifdef DF_POSIX /* DF_MSS */
  37. #include <misc.h>
  38. #include <bsdlib.h>
  39. #endif
  40.  
  41. #ifndef lint
  42. char copyright[] =
  43. "@(#) Copyright (c) 1989 The Regents of the University of California.\n\
  44.  All rights reserved.\n";
  45. #endif /* not lint */
  46.  
  47. #ifndef lint
  48. static char sccsid[] = "@(#)ls.c    5.48 (Berkeley) 4/3/91";
  49. #endif /* not lint */
  50.  
  51. #ifdef DF_POSIX /* DF_DSC */
  52. #include <sys/cdefs.h>
  53. #else
  54. #include <sys/param.h>
  55. #endif
  56. #include <sys/stat.h>
  57. #ifdef _POSIX_SOURCE /* DF_DSC */
  58. #include <stdlib.h>
  59. #include <unistd.h>
  60. #else
  61. #include <sys/ioctl.h>
  62. #endif
  63. #include <dirent.h>
  64. #include <string.h>
  65. #include <errno.h>
  66. #include <stdio.h>
  67. #include "ls.h"
  68.  
  69. int (*sortfcn) __P((LS *, LS *));
  70. void (*printfcn) __P((LS *, register int));
  71. #ifndef _POSIX_SOURCE
  72. int lstat();
  73. #endif
  74. extern char *emalloc __P((u_int));
  75. #if WIN_NT
  76. extern int acccmp __P((LS *, LS *)), modcmp __P((LS *, LS *));
  77. extern int namecmp __P((LS *, LS *));
  78. extern void prcopy __P((register char *, register char *, int));
  79. extern void printcol __P((LS *, register int));
  80. extern void printlong __P((LS *, register int));
  81. extern void printscol __P((register LS *, register int));
  82. extern int revacccmp __P((LS *, LS *)), revmodcmp __P((LS *, LS *));
  83. extern int revnamecmp __P((LS *, LS *)), revstatcmp __P((LS *, LS *));
  84. extern int statcmp __P((LS *, LS *));
  85. extern void nomem __P((void));
  86. extern void usage __P((void));
  87. extern int globulate __P((int, int, char **));
  88. extern void deglobulate __P((void));
  89. extern int globulated_argc;
  90. extern char **globulated_argv;
  91. pid_t ppid;
  92. int globulation;
  93. #endif
  94.  
  95. int termwidth = 80;        /* default terminal width */
  96.  
  97. /* flags */
  98. int f_accesstime;        /* use time of last access */
  99. int f_column;            /* columnated format */
  100. int f_group;            /* show group ownership of a file */
  101. int f_ignorelink;        /* indirect through symbolic link operands */
  102. int f_inode;            /* print inode */
  103. int f_kblocks;            /* print size in kilobytes */
  104. int f_listalldot;        /* list . and .. as well */
  105. int f_listdir;            /* list actual directory, not contents */
  106. int f_listdot;            /* list files beginning with . */
  107. int f_longform;            /* long listing format */
  108. int f_needstat;            /* if need to stat files */
  109. int f_newline;            /* if precede with newline */
  110. int f_nonprint;            /* show unprintables as ? */
  111. int f_nosort;            /* don't sort output */
  112. int f_recursive;        /* ls subdirectories also */
  113. int f_reversesort;        /* reverse whatever sort is used */
  114. int f_sectime;            /* print the real time for all files */
  115. int f_singlecol;        /* use single column output */
  116. int f_size;            /* list size in short listing */
  117. int f_statustime;        /* use time of last mode change */
  118. int f_dirname;            /* if precede with directory name */
  119. int f_timesort;            /* sort by time vice name */
  120. int f_total;            /* if precede with "total" line */
  121. int f_type;            /* add type character for non-regular files */
  122.  
  123. #if _POSIX_SOURCE
  124. int (*statfcn) __P((const char *, struct stat *));
  125. #else
  126. int (*statfcn)(), stat(), lstat();
  127. #endif
  128.  
  129. #if WIN_NT
  130. void doargs __P((int, char **));
  131. void displaydir __P((LS *, register int));
  132. void subdir __P((LS *));
  133. int tabdir __P((LS *, LS **, char **));
  134. #endif
  135.  
  136. int
  137. #if __STDC__
  138. main (int argc, char **argv)
  139. #else
  140. main(argc, argv)
  141.     int argc;
  142.     char **argv;
  143. #endif
  144. {
  145. #ifdef _POSIX_SOURCE /* DF_DSC */
  146.     extern int optind;
  147. #else
  148.     extern int optind, stat();
  149.     struct winsize win;
  150. #endif
  151.  
  152.     int ch;
  153. #if !WIN_NT
  154.     char *p, *getenv();
  155.     int acccmp(), modcmp(), namecmp(), prcopy(), printcol();
  156.     int printlong(), printscol(), revacccmp(), revmodcmp(), revnamecmp();
  157.     int revstatcmp(), statcmp();
  158. #endif
  159.  
  160. #if WIN_NT
  161.     ppid = getppid();
  162.     if (ppid == (pid_t) 1) /* if parent is CMD.EXE */
  163.     {
  164.         globulation = globulate(1, argc, argv);
  165.         if (globulation == 0)
  166.         {
  167.             argc = globulated_argc;
  168.             argv = globulated_argv;
  169.         }
  170.     }
  171. #endif
  172.     /* terminal defaults to -Cq, non-terminal defaults to -1 */
  173.     if (isatty(1)) {
  174.         f_nonprint = 1;
  175. #ifndef _POSIX_SOURCE /* DF_MSS */
  176.         if (ioctl(1, TIOCGWINSZ, &win) == -1 || !win.ws_col) {
  177.             if (p = getenv("COLUMNS"))
  178.                 termwidth = atoi(p);
  179.         }
  180.         else
  181.             termwidth = win.ws_col;
  182. #endif
  183.         f_column = 1;
  184.     } else
  185.         f_singlecol = 1;
  186.  
  187.     /* root is -A automatically */
  188.     if (!getuid())
  189.         f_listdot = 1;
  190.  
  191. #if _POSIX_SOURCE
  192.     while ((ch = getopt(argc, argv, "1ACFLRTacdfiklqrstu")) != EOF) {
  193. #else
  194.     while ((ch = getopt(argc, argv, "1ACFLRTacdfgiklqrstu")) != EOF) {
  195. #endif
  196.         switch (ch) {
  197.         /*
  198.          * -1, -C and -l all override each other
  199.          * so shell aliasing works right
  200.          */
  201.         case '1':
  202.             f_singlecol = 1;
  203.             f_column = f_longform = 0;
  204. #if _POSIX_SOURCE
  205.             f_group = 0;
  206. #endif
  207.             break;
  208.         case 'C':
  209.             f_column = 1;
  210.             f_longform = f_singlecol = 0;
  211. #if _POSIX_SOURCE
  212.             f_group = 0;
  213. #endif
  214.             break;
  215.         case 'l':
  216.             f_longform = 1;
  217. #if _POSIX_SOURCE
  218.             f_group = 1;
  219. #endif
  220.             f_column = f_singlecol = 0;
  221.             break;
  222.         /* -c and -u override each other */
  223.         case 'c':
  224.             f_statustime = 1;
  225.             f_accesstime = 0;
  226.             break;
  227.         case 'u':
  228.             f_accesstime = 1;
  229.             f_statustime = 0;
  230.             break;
  231.         case 'F':
  232.             f_type = 1;
  233.             break;
  234.         case 'L':
  235.             f_ignorelink = 1;
  236.             break;
  237.         case 'R':
  238.             f_recursive = 1;
  239.             break;
  240.         case 'a':
  241.             f_listalldot = 1;
  242.             /* FALLTHROUGH */
  243.         case 'A':
  244.             f_listdot = 1;
  245.             break;
  246.         case 'd':
  247.             f_listdir = 1;
  248.             break;
  249.         case 'f':
  250.             f_nosort = 1;
  251.             break;
  252. #if !_POSIX_SOURCE
  253.         case 'g':
  254.             f_group = 1;
  255.             break;
  256. #endif
  257.         case 'i':
  258.             f_inode = 1;
  259.             break;
  260.         case 'k':
  261.             f_kblocks = 1;
  262.             break;
  263.         case 'q':
  264.             f_nonprint = 1;
  265.             break;
  266.         case 'r':
  267.             f_reversesort = 1;
  268.             break;
  269.         case 's':
  270.             f_size = 1;
  271.             break;
  272.         case 'T':
  273.             f_sectime = 1;
  274.             break;
  275.         case 't':
  276.             f_timesort = 1;
  277.             break;
  278.         default:
  279.         case '?':
  280.             usage();
  281.         }
  282.     }
  283.     argc -= optind;
  284.     argv += optind;
  285.  
  286.     /* -d turns off -R */
  287.     if (f_listdir)
  288.         f_recursive = 0;
  289.  
  290.     /* if need to stat files */
  291.     f_needstat = f_longform || f_recursive || f_timesort ||
  292.         f_size || f_type;
  293.  
  294.     /* select a sort function */
  295.     if (f_reversesort) {
  296.         if (!f_timesort)
  297.             sortfcn = revnamecmp;
  298.         else if (f_accesstime)
  299.             sortfcn = revacccmp;
  300.         else if (f_statustime)
  301.             sortfcn = revstatcmp;
  302.         else /* use modification time */
  303.             sortfcn = revmodcmp;
  304.     } else {
  305.         if (!f_timesort)
  306.             sortfcn = namecmp;
  307.         else if (f_accesstime)
  308.             sortfcn = acccmp;
  309.         else if (f_statustime)
  310.             sortfcn = statcmp;
  311.         else /* use modification time */
  312.             sortfcn = modcmp;
  313.     }
  314.  
  315.     /* select a print function */
  316.     if (f_singlecol)
  317.         printfcn = printscol;
  318.     else if (f_longform)
  319.         printfcn = printlong;
  320.     else
  321.         printfcn = printcol;
  322.  
  323. #if _POSIX_SOURCE
  324.     statfcn = stat;
  325. #else
  326.     /* if -l, -d or -F, and not ignoring the link, use lstat() */
  327.     statfcn =
  328.         (f_longform || f_listdir || f_type) && !f_ignorelink ? lstat : stat;
  329. #endif
  330.  
  331.     if (!argc) {
  332.         static char dot[] = ".";
  333.  
  334.         argc = 1;
  335.         argv[0] = dot;
  336.         argv[1] = NULL;
  337.     }
  338.     doargs(argc, argv);
  339.  
  340. #ifndef _POSIX_SOURCE /* DF_MSS: fclosing not working in POSIX */
  341.     fflush (stderr);
  342.     fflush (stdout);
  343.     fclose (stderr);
  344.     fclose (stdout);
  345.     fclose (stdin);
  346. #endif
  347.  
  348. #if WIN_NT
  349.     if (ppid == (pid_t) 1 && globulation == 0)
  350.         deglobulate();
  351. #endif
  352.     return EXIT_SUCCESS;
  353. }
  354.  
  355. static char path[MAXPATHLEN + 1];
  356. static char *endofpath = path;
  357.  
  358. void
  359. #if __STDC__
  360. doargs (int argc, char **argv)
  361. #else
  362. doargs(argc, argv)
  363.     int argc;
  364.     char **argv;
  365. #endif
  366. {
  367.     register LS *dstatp, *rstatp;
  368.     register int cnt, dircnt, maxlen, regcnt;
  369.     LS *dstats, *rstats;
  370.     struct stat sb;
  371.     char top[MAXPATHLEN + 1];
  372.     u_long blocks;
  373.  
  374.     /*
  375.      * walk through the operands, building separate arrays of LS
  376.      * structures for directory and non-directory files.
  377.      */
  378.     dstats = rstats = NULL;
  379.     for (dircnt = regcnt = 0; *argv; ++argv) {
  380. #if BETA
  381. printf("doargs - before stat; *argv: \"%s\"\n", *argv);
  382. #endif
  383. #if _POSIX_SOURCE
  384.         if (statfcn(*argv, &sb)) {
  385. # if BETA
  386. printf("doargs - after non-zero stat\n");
  387. # endif
  388. #else
  389.         if (statfcn(*argv, &sb) &&
  390.             (statfcn == lstat || lstat(*argv, &sb))) {
  391. #endif
  392.             (void)fprintf(stderr,
  393.                 "ls: %s: %s\n", *argv, strerror(errno));
  394.             if (errno == ENOENT)
  395.                 continue;
  396. #if WIN_NT
  397.             if (ppid == (pid_t) 1 && globulation == 0)
  398.                 deglobulate();
  399. #endif
  400.             exit(EXIT_FAILURE);
  401.         }
  402. #if BETA
  403. printf("*argv: \"%s\"; S_ISDIR: %d; sb.st_size: %ld\n",
  404.     *argv, S_ISDIR(sb.st_mode), (long) sb.st_size);
  405. #endif
  406. #if DF_POSIX
  407.         if (S_ISDIR(sb.st_mode))
  408.             sb.st_size = (off_t) 0;
  409. #endif
  410.         if (S_ISDIR(sb.st_mode) && !f_listdir) {
  411.             if (!dstats)
  412.                 dstatp = dstats = (LS *)emalloc((u_int)argc *
  413.                     (sizeof(LS)));
  414.             dstatp->name = *argv;
  415.             dstatp->lstat = sb;
  416.             ++dstatp;
  417.             ++dircnt;
  418.         }
  419.         else {
  420.             if (!rstats) {
  421.                 rstatp = rstats = (LS *)emalloc((u_int)argc *
  422.                     (sizeof(LS)));
  423.                 blocks = 0;
  424.                 maxlen = -1;
  425.             }
  426.             rstatp->name = *argv;
  427.             rstatp->lstat = sb;
  428.  
  429.             /* save name length for -C format */
  430.             rstatp->len = strlen(*argv);
  431.  
  432.             if (f_nonprint)
  433.                 prcopy(*argv, *argv, rstatp->len);
  434.  
  435.             /* calculate number of blocks if -l/-s formats */
  436.             if (f_longform || f_size)
  437. #ifdef _POSIX_SOURCE /* DF_MSS */
  438.                 blocks += (sb.st_size/BLOCK_SIZE) + 1;
  439. #else
  440.                 blocks += sb.st_blocks;
  441. #endif
  442.  
  443.             /* save max length if -C format */
  444.             if (f_column && maxlen < rstatp->len)
  445.                 maxlen = rstatp->len;
  446.  
  447.             ++rstatp;
  448.             ++regcnt;
  449.         }
  450.     }
  451.     /* display regular files */
  452.     if (regcnt) {
  453. #ifndef _POSIX_SOURCE /* DF_MSS */
  454.         rstats[0].lstat.st_btotal = blocks;
  455.         rstats[0].lstat.st_maxlen = maxlen;
  456. #endif 
  457.  
  458.         displaydir(rstats, regcnt);
  459.         f_newline = f_dirname = 1;
  460.     }
  461.     /* display directories */
  462.     if (dircnt) {
  463.         register char *p;
  464.  
  465.         f_total = 1;
  466.         if (dircnt > 1) {
  467. #if _POSIX_SOURCE
  468.             (void)getcwd(top, sizeof top - 1);
  469. #else
  470.             (void)getwd(top);
  471. #endif
  472. #if __STDC__
  473.             qsort((void *)dstats, (size_t)dircnt, sizeof(LS), (int (*)(const void *, const void *))sortfcn);
  474. #else
  475.             qsort((char *)dstats, dircnt, sizeof(LS), sortfcn);
  476. #endif
  477.             f_dirname = 1;
  478.         }
  479.         for (cnt = 0; cnt < dircnt; ++dstats) {
  480.             for (endofpath = path, p = dstats->name;
  481.                 (*endofpath = *p++) != '\0'; ++endofpath);
  482. #if BETA
  483. puts("before subdir(dstats)");
  484. #endif
  485.             subdir(dstats);
  486.             f_newline = 1;
  487.             if (++cnt < dircnt && chdir(top)) {
  488.                 (void)fprintf(stderr, "ls: %s: %s\n",
  489.                     top, strerror(errno));
  490. #if WIN_NT
  491.                 if (ppid == (pid_t) 1 && globulation == 0)
  492.                     deglobulate();
  493. #endif
  494.                 exit(EXIT_FAILURE);
  495.             }
  496.         }
  497.     }
  498. }
  499.  
  500. void
  501. #if __STDC__
  502. displaydir (LS *stats, register int num)
  503. #else
  504. displaydir(stats, num)
  505.     LS *stats;
  506.     register int num;
  507. #endif
  508. {
  509.     register char *p, *savedpath;
  510.     LS *lp;
  511.  
  512.     if (num > 1 && !f_nosort) {
  513. #ifndef _POSIX_SOURCE /* DF_MSS */
  514.         u_long save1, save2;
  515.  
  516.         save1 = stats[0].lstat.st_btotal;
  517.         save2 = stats[0].lstat.st_maxlen;
  518. #endif
  519. #if __STDC__
  520.         qsort((void *)stats, (size_t)num, sizeof(LS), (int (*)(const void *, const void *))sortfcn);
  521. #else
  522.         qsort((char *)stats, num, sizeof(LS), sortfcn);
  523. #endif
  524. #ifndef _POSIX_SOURCE /* DF_MSS */
  525.         stats[0].lstat.st_btotal = save1;
  526.         stats[0].lstat.st_maxlen = save2;
  527. #endif
  528.     }
  529.     printfcn(stats, num);
  530.  
  531.     if (f_recursive) {
  532.         savedpath = endofpath;
  533.         for (lp = stats; num--; ++lp) {
  534.             if (!S_ISDIR(lp->lstat.st_mode))
  535.                 continue;
  536.             p = lp->name;
  537.             if (p[0] == '.' && (!p[1] || p[1] == '.' && !p[2]))
  538.                 continue;
  539.             if (endofpath != path && endofpath[-1] != '/')
  540.                 *endofpath++ = '/';
  541.             for (; (*endofpath = *p++) != '\0'; ++endofpath);
  542.             f_newline = f_dirname = f_total = 1;
  543. #if BETA
  544. puts("before subdir(lp)");
  545. #endif
  546.             subdir(lp);
  547.             *(endofpath = savedpath) = '\0';
  548.         }
  549.     }
  550. }
  551.  
  552. void
  553. #if __STDC__
  554. subdir (LS *lp)
  555. #else
  556. subdir(lp)
  557.     LS *lp;
  558. #endif
  559. {
  560.     LS *stats;
  561.     int num;
  562.     char *names;
  563.  
  564.     if (f_newline)
  565.         (void)putchar('\n');
  566.     if (f_dirname)
  567.         (void)printf("%s:\n", path);
  568.  
  569.     if (chdir(lp->name)) {
  570.         (void)fprintf(stderr, "ls: %s: %s\n", lp->name,
  571.              strerror(errno));
  572.         return;
  573.     }
  574.     if ((num = tabdir(lp, &stats, &names)) != 0) {
  575.         displaydir(stats, num);
  576.         (void)free((char *)stats);
  577.         (void)free((char *)names);
  578.     }
  579.     if (chdir("..")) {
  580.         (void)fprintf(stderr, "ls: ..: %s\n", strerror(errno));
  581. #if WIN_NT
  582.         if (ppid == (pid_t) 1 && globulation == 0)
  583.             deglobulate();
  584. #endif
  585.         exit(EXIT_FAILURE);
  586.     }
  587. }
  588.  
  589. int
  590. #if __STDC__
  591. tabdir (LS *lp, LS **s_stats, char **s_names)
  592. #else
  593. tabdir(lp, s_stats, s_names)
  594.     LS *lp, **s_stats;
  595.     char **s_names;
  596. #endif
  597. {
  598.     register DIR *dirp;
  599.     register int cnt, maxentry, maxlen;
  600.     register char *p, *names;
  601.     struct dirent *dp;
  602.     u_long blocks;
  603.     LS *stats;
  604.  
  605.     if (!(dirp = opendir("."))) {
  606.         (void)fprintf(stderr, "ls: %s: %s\n", lp->name,
  607.             strerror(errno));
  608.         return(0);
  609.     }
  610. #if BETA
  611. printf("a opendir; f_needstat: %d\n", f_needstat);
  612. #endif
  613.     blocks = maxentry = maxlen = 0;
  614.     stats = NULL;
  615.     for (cnt = 0; (dp = readdir(dirp)) != NULL;) {
  616.         /* this does -A and -a */
  617.         p = dp->d_name;
  618. #if BETA
  619. printf("a readdir; file: \"%s\"\n", p);
  620. #endif
  621.         if (p[0] == '.') {
  622.             if (!f_listdot)
  623.                 continue;
  624.             if (!f_listalldot && (!p[1] || p[1] == '.' && !p[2]))
  625.                 continue;
  626.         }
  627. #if BETA
  628. puts("after dot check");
  629. #endif
  630.         if (cnt == maxentry) {
  631.             if (!maxentry) {
  632. #if BETA
  633. int err;
  634. #endif
  635. #ifdef _POSIX_SOURCE /* DF_MSS */
  636.                 if( lp->lstat.st_size == (off_t) 0 )
  637.                     lp->lstat.st_size = (off_t) 7000;
  638. #if BETA
  639. printf("st_size: %u\n", (u_int)lp->lstat.st_size);
  640. #endif
  641. #endif
  642.                 *s_names = names =
  643.                     emalloc((u_int)lp->lstat.st_size);
  644. #if BETA
  645. err = errno;
  646. if (names == NULL) {
  647.     printf("errno: %d\n", err);
  648.     nomem();
  649. }
  650. #endif
  651.             }
  652. #define    DEFNUM    256
  653.             maxentry += DEFNUM;
  654.             if (!(*s_stats = stats = (LS *)realloc((char *)stats,
  655.                 (u_int)maxentry * sizeof(LS))))
  656.                 nomem();
  657.         }
  658. #if BETA
  659. puts("after maxentry check");
  660. #endif
  661.         if (f_needstat && statfcn(dp->d_name, &stats[cnt].lstat) &&
  662. #if _POSIX_SOURCE
  663.             statfcn == stat ) {
  664. #else
  665.             statfcn == stat && lstat(dp->d_name, &stats[cnt].lstat)) {
  666. #endif
  667.             /*
  668.              * don't exit -- this could be an NFS mount that has
  669.              * gone away.  Flush stdout so the messages line up.
  670.              */
  671.             (void)fflush(stdout);
  672.             (void)fprintf(stderr,
  673.                 "ls: %s: %s\n", dp->d_name, strerror(errno));
  674.             continue;
  675.         }
  676.         stats[cnt].name = names;
  677. #if BETA
  678. printf("after f_needstat check; dp->d_name: \"%s\"; names: %p; len: %u\n",
  679.     dp->d_name, names, (unsigned int) strlen(dp->d_name));
  680. #endif
  681.  
  682.         if (f_nonprint)
  683. #ifdef _POSIX_SOURCE /* DF_MSS */
  684.             prcopy(dp->d_name, names, (int)strlen(dp->d_name));
  685.         else
  686.             bcopy(dp->d_name, names, (int)strlen(dp->d_name));
  687. #if BETA
  688. puts("after nonprint check");
  689. #endif
  690.         names += strlen(dp->d_name);
  691. #else
  692.             prcopy(dp->d_name, names, (int)dp->d_namlen);
  693.         else
  694.             bcopy(dp->d_name, names, (int)dp->d_namlen);
  695.         names += dp->d_namlen;
  696. #endif
  697.         *names++ = '\0';
  698. #if BETA
  699. puts("after names mucking");
  700. #endif
  701.  
  702.         /*
  703.          * get the inode from the directory, so the -f flag
  704.          * works right.
  705.          */
  706. #ifndef _POSIX_SOURCE /* DF_MSS */
  707.         stats[cnt].lstat.st_ino = dp->d_ino;
  708. #endif
  709.  
  710.         /* save name length for -C format */
  711. #ifdef _POSIX_SOURCE /* DF_MSS */
  712.                 stats[cnt].len = strlen(dp->d_name);
  713. #else
  714.                 stats[cnt].len = dp->d_namlen;
  715. #endif
  716.  
  717.         /* calculate number of blocks if -l/-s formats */
  718.         if (f_longform || f_size)
  719. #ifdef _POSIX_SOURCE /* DF_MSS: POSIX does not support st_blocks defaulting to 10 */
  720.             blocks += (stats[cnt].lstat.st_size/BLOCK_SIZE) + 1;
  721. #else
  722.             blocks += stats[cnt].lstat.st_blocks;
  723. #endif
  724.         /* save max length if -C format */
  725. #ifdef _POSIX_SOURCE /* DF_MSS */
  726.         if (f_column && maxlen < (int)strlen(dp->d_name))
  727.             maxlen = strlen(dp->d_name);
  728. #else
  729.         if (f_column && maxlen < (int)dp->d_namlen)
  730.             maxlen = dp->d_namlen;
  731. #endif
  732.         ++cnt;
  733. #if BETA
  734. puts("end-o-loop");
  735. #endif
  736.     }
  737.     (void)closedir(dirp);
  738.  
  739.     if (cnt) {
  740. #ifndef _POSIX_SOURCE /* DF_MSS */
  741.         stats[0].lstat.st_btotal = blocks;
  742.         stats[0].lstat.st_maxlen = maxlen;
  743. #endif
  744.     } else if (stats) {
  745.  
  746.         (void)free((char *)stats);
  747.         (void)free((char *)names);
  748.     }
  749.     return(cnt);
  750. }
  751.